home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / BenchMarks / Dhrystone / dhry.p < prev    next >
Text File  |  1993-01-25  |  37KB  |  833 lines

  1. (*
  2.  ****************************************************************************
  3.  *
  4.  *                   "DHRYSTONE" Benchmark Program
  5.  *                   -----------------------------
  6.  *                                                                            
  7.  *  Version:    Pascal, Version 2.0
  8.  *                                                                            
  9.  *  File:       dhry.p
  10.  *
  11.  *  Date:       March 3, 1988
  12.  *
  13.  *  Author:     Reinhold P. Weicker
  14.  *                      Siemens AG, E STE 35
  15.  *                      Postfach 3240
  16.  *                      8520 Erlangen
  17.  *                      Germany (West)
  18.  *                              Phone:  [xxx-49]-9131-7-20330
  19.  *                                      (8-17 Central European Time)
  20.  *                              Usenet: ..!mcvax!unido!estevax!weicker
  21.  *
  22.  *              Original Version (in Ada) published in
  23.  *              "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
  24.  *              pp. 1013 - 1030, together with the statistics
  25.  *              on which the distribution of statements etc. is based,
  26.  *
  27.  *              This version uses calls to the Pascal runtime library of the
  28.  *              Berkeley UNIX system (4.3 bsd) for time measurement.
  29.  *              For measurements on other systems, these calls need to be
  30.  *              modified.                                
  31.  *                                                                           
  32.  *  Collection of Results:
  33.  *              Reinhold Weicker (address see above) and
  34.  *              
  35.  *              Rick Richardson
  36.  *              PC Research. Inc.
  37.  *              94 Apple Orchard Drive
  38.  *              Tinton Falls, NJ 07724
  39.  *                      Phone:  (201) 834-1378 (9-17 EST)               
  40.  *                      Usenet: ...!seismo!uunet!pcrat!rick
  41.  *
  42.  *      Please send results to Reinhold Weicker and/or Rick Richardson.
  43.  *      Complete information should be given on hardware and software used.
  44.  *      Hardware information includes: Machine type, CPU, type and size
  45.  *      of caches; for microprocessors: clock frequency, memory speed
  46.  *      (number of wait states).
  47.  *      Software information includes: Compiler (and runtime library)
  48.  *      manufacturer and version, compilation switches, OS version.
  49.  *      The Operating System version may give an indication about the
  50.  *      compiler; Dhrystone itself performs no OS calls in the measurement loop.
  51.  *
  52.  *      The complete output generated by the program should be mailed
  53.  *      such that at least some checks for correctness can be made.
  54.  *
  55.  ****************************************************************************
  56.  *
  57.  *  History:    This version Pascal/2.0 has been made for two reasons:
  58.  *
  59.  *              1) There is a need for a common Pascal version of
  60.  *              Dhrystone. Although translation from the published (Ada)
  61.  *              version to Pascal is straightforward in most aspects,
  62.  *              there are cases where it may not be obvious to everyone.
  63.  *              There should be, as far as possible, only one Pascal version
  64.  *              of Dhrystone such that results can be compared without
  65.  *              restrictions. Also, a Pascal version of Dhrystone has not yet
  66.  *              found a network distribution comparable to the C version
  67.  *              (version 1.1) distributed by Rick Richardson.
  68.  *              
  69.  *              2) As far as it is possible without changes to the Dhrystone
  70.  *              statistics, optimizing compilers should be prevented from
  71.  *              removing significant statements.
  72.  *
  73.  *              This Pascal version 2.0 has been made consistent with the
  74.  *              C version 2.0; therefore the acknowledgments for the C version
  75.  *              are due for the Pascal version as well: I thank
  76.  *              Rick Richardson (Tinton Falls, NJ), Chaim Benedelac (Nat.
  77.  *              Semi.), David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
  78.  *              Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
  79.  *              for their help with comments on earlier versions of the
  80.  *              benchmark.
  81.  *
  82.  *  Changes:    In the initialization part, this version differs 
  83.  *              from the Pascal version previously distributed by Reinhold
  84.  *              Weicker, the number of runs through Dhrystone is obtained
  85.  *              interactively from the terminal. Output of the result 
  86.  *              has been changed to conform to the C version (2.0).
  87.  *              The changes in the initialization part and in the printing
  88.  *              of the result have no impact on performance measurement 
  89.  *              since they are outside the measaurement loop.
  90.  *              
  91.  *              Inside the measurement loop, this version follows the
  92.  *              version previously distributed by Reinhold Weicker.
  93.  *              As a correction to the published version, a statement
  94.  *              initializing Array2Glob [8,7] (outside the measurement
  95.  *              loop) has been added. Otherwise, this array element would
  96.  *              have an undefined value.
  97.  *
  98.  *              At several places in the benchmark, code has been added,
  99.  *              but within the measurement loop only in branches that 
  100.  *              are not executed. The intention is that optimizing compilers
  101.  *              should be prevented from moving code out of the measurement
  102.  *              loop, or from removing code altogether. Since the statements
  103.  *              that are executed within the measurement loop have NOT been
  104.  *              changed, all numbers defining the "Dhrystone distribution"
  105.  *              (distribution of statements, operand types and locality)
  106.  *              still hold. Except for sophisticated optimizing compilers,
  107.  *              execution times for this version should be the same as
  108.  *              for previous versions.
  109.  *
  110.  *        Since it has proven difficult to subtract the time for the
  111.  *        measurement loop overhead in a correct way, the loop check
  112.  *        has been made a part of the benchmark. This does have
  113.  *        an impact - though a very minor one - on the distribution
  114.  *        statistics which have been updated for this version.
  115.  *
  116.  *              All changes within the measurement loop are described
  117.  *              and discussed in the companion paper "Rationale for
  118.  *              Dhrystone version 2".
  119.  *
  120.  *              Because of the self-imposed limitation that the order and
  121.  *              distribution of the executed statements should not be
  122.  *              changed, there are still cases where optimizing compilers
  123.  *              may not generate code for some statements. To a certain
  124.  *              degree, this is unavoidable for small synthetic benchmarks.
  125.  *              Users of the benchmark are advised to check code listings
  126.  *              whether code is generated for all statements of Dhrystone.
  127.  *
  128.  ***************************************************************************
  129.  *
  130.  *  Compilation model and measurement (IMPORTANT):
  131.  *
  132.  *  This program contains the Dhrystone program, including measurement setup,
  133.  *  in one file. The original (Ada) program contained three packages,
  134.  *  - a package with global type definitions,
  135.  *  - Pack_1, containing the main program (Proc_0 in Ada) and procedures
  136.  *            Proc_1, ... , Proc_5,
  137.  *  - Pack_2, containing Proc_6, ... , Proc_8, Func_1, ..., Func_3.
  138.  *  Since ISO/ANSI Standard Pascal provides no means to express separate
  139.  *  compilation (although many Pascal implementations provide such a feature),
  140.  *  it is not possible to formulate a portable Pascal version with the program
  141.  *  in several modules, corresponding more closely to the Ada and C versions.
  142.  *  Therefore, no attempt has been made to construct a Pascal version with
  143.  *  the program consisting of several modules.
  144.  *                                                                           
  145.  *  This difference may impact execution time because the compiler can
  146.  *  perform more data flow analysis for a single-module program;
  147.  *  sophisticated compilers may be able to suppress code generation for
  148.  *  some parts of the program.
  149.  *  Users should check machine code listings generated by the compiler
  150.  *  to ensure that code is generated for all parts of the program.
  151.  *
  152.  *  The following "ground rules" apply for measurements:
  153.  *  - No procedure merging
  154.  *  - Otherwise, compiler optimizations are allowed but should be indicated
  155.  *  See the companion paper "Rationale for Dhrystone Version 2" for a more
  156.  *  detailed discussion of these ground rules.
  157.  *
  158.  *  For 16-Bit processors (e.g. 80x86), times for all compilation models
  159.  *  ("small", "medium", "large") should be given if possible, together
  160.  *  with a definition of these models for the compiler system used.
  161.  *
  162.  **************************************************************************
  163.  *
  164.  *  Dhrystone (Pascal version) statistics:
  165.  *
  166.  *  [Comment from the first distribution by Reinhold Weicker,
  167.  *   the distribution statistics have been updated for Version 2.0.
  168.  *   Note that because of language differences, the numbers are different
  169.  *   from the Ada version. The main difference is that the variables that
  170.  *   are local variables of "Proc_0" (Ada) or "main" (C) are global
  171.  *   variables in the Pascal version.]
  172.  *                                                                           
  173.  *  The following program contains statements of a high level programming    
  174.  *  language (here: Pascal) in a distribution considered representative:     
  175.  *                                                                           
  176.  *    assignments                  58
  177.  *    control statements           28
  178.  *    procedure, function calls    15
  179.  *                                                                           
  180.  *  100 statements are dynamically executed. The program is balanced with    
  181.  *  respect to the three aspects:                                            
  182.  *                                                                           
  183.  *    - statement type                                                       
  184.  *    - operand type (for simple data types)                                 
  185.  *    - operand access                                                       
  186.  *         operand global, local, parameter, or constant.                    
  187.  *           There is no static nesting of blocks or procedures,             
  188.  *           therefore all variables are either global or local.             
  189.  *                                                                           
  190.  *  The combination of these three aspects is balanced only approximately.   
  191.  *                                                                           
  192.  *  1. Statement Type:                                                       
  193.  *  -----------------             number
  194.  *                                                                           
  195.  *     V1 := V2                   15                                         
  196.  *     V := Constant              12                                         
  197.  *       (incl. V1 := F(..)                                                  
  198.  *     Assignment,                 7                                         
  199.  *       with array element                                                  
  200.  *     Assignment,                 6                                         
  201.  *       with record component                                               
  202.  *                                --                                       
  203.  *                                40       40                                
  204.  *                                                                           
  205.  *     X := Y +|-|and|or Z         5                                         
  206.  *     X := Y +|-|"=" Constant     6                                         
  207.  *     X := X +|- 1                3                                         
  208.  *     X := Y *|/ Z                2                                         
  209.  *     X := Expression,            1                                         
  210.  *          two operators                                                    
  211.  *     X := Expression,            1                                         
  212.  *          three operators                                                  
  213.  *                                --                                         
  214.  *                                18       18                                
  215.  *                                                                           
  216.  *     if .... then ....          14                                         
  217.  *       with "else"      7                                                  
  218.  *       without "else"   7                                                  
  219.  *           executed        3                                               
  220.  *           not executed    4                                               
  221.  *     for I in 1..N do ...        7  |  counted every time                  
  222.  *     while ... do ...            4  |  the loop condition                  
  223.  *     repeat ... until            1  |  is evaluated                        
  224.  *     case ... end                1                                         
  225.  *     with                        1                                         
  226.  *                                --                                         
  227.  *                                28       28                                
  228.  *                                                                           
  229.  *     P (...)  procedure call    10                                         
  230.  *     X := F (...)                                                          
  231.  *             function  call      5                                         
  232.  *                                --                                         
  233.  *                                15       15                                
  234.  *                                        ---                              
  235.  *                                        101                                
  236.  *                                                                           
  237.  *    22 of the 58 assignments have a variable of a constrained              
  238.  *    (sub-)type as their destination. In general, discriminant checks       
  239.  *    will be necessary in these cases; however, the compiler may            
  240.  *    optimize out some of these checks.                                     
  241.  *                                                                           
  242.  *    The average number of parameters in procedure or function calls        
  243.  *    is 1.80 (not counting the function values as implicit parameters).     
  244.  *                                                                           
  245.  *                                                                           
  246.  *  2. Operators                                                             
  247.  *  ------------                                                             
  248.  *                          number    approximate                            
  249.  *                                    percentage                             
  250.  *                                                                           
  251.  *    Arithmetic             27          52.9                                
  252.  *                                                                           
  253.  *       +                     16          31.4                              
  254.  *       -                      7          13.7                              
  255.  *       *                      3           5.9                              
  256.  *       div                    1           2.0                              
  257.  *                                                                           
  258.  *    Comparison             20           39.2                               
  259.  *                                                                           
  260.  *       =                      9           17.6                             
  261.  *       <>                     4            7.8                             
  262.  *       >                      1            2.0                             
  263.  *       <                      3            5.9                             
  264.  *       >=                     1            2.0                             
  265.  *       <=                     2            3.9                             
  266.  *                                                                           
  267.  *    Logic                   4            7.8                               
  268.  *                                                                           
  269.  *       AND                    1            2.0                             
  270.  *       OR                     1            2.0                             
  271.  *       NOT                    2            3.9                             
  272.  *                                                                           
  273.  *                           --          -----                               
  274.  *                           51           99.9                               
  275.  *                                                                           
  276.  *                                                                           
  277.  *  3. Operand Type (counted once per operand reference):                    
  278.  *  ---------------                                                          
  279.  *                          number    approximate                            
  280.  *                                    percentage                             
  281.  *                                                                           
  282.  *     Integer               135        54.7 %                               
  283.  *     Character              47        19.0 %                               
  284.  *     Enumeration            31        12.6 %                               
  285.  *     Boolean                13         5.3 %                               
  286.  *     Pointer                11         4.5 %                               
  287.  *     String30                6         2.4 %                               
  288.  *     Array                   2         0.8 %                               
  289.  *     Record                  2         0.8 %                               
  290.  *                           ---       -------                               
  291.  *                           247        100.1 %
  292.  *                                                                           
  293.  *  When there is an access path leading to the final operand (e.g. a record 
  294.  *  component), only the final data type on the access path is counted.      
  295.  *                                                                           
  296.  *  There are 16 accesses to components of a record, 9 of them go to         
  297.  *  a component in a variant part. For some of these accesses, the           
  298.  *  compiler may suppress generation of code checking the tag field          
  299.  *  during optimization.                                                     
  300.  *                                                                           
  301.  *                                                                           
  302.  *  3. Operand Locality:                                                     
  303.  *  -------------------                                                      
  304.  *                                                                           
  305.  *     local variable               84        34.0 %                         
  306.  *     global variable              58        23.5 %                         
  307.  *     parameter                    45        18.2 %                         
  308.  *        value                        23         9.3 %                      
  309.  *        reference                    22         8.9 %                      
  310.  *     function result               5         2.0 %                         
  311.  *     constant                     55        22.3 %                         
  312.  *                                 ---       -------                         
  313.  *                                 247       100.0 %                         
  314.  *                                                                           
  315.  *                                                                           
  316.  *  The program does not compute anything meaningful, but it is syntactically
  317.  *  and semantically correct. All variables have a value assigned to them    
  318.  *  before they are used as a source operand.                                
  319.  *                                                                           
  320.  *  There may be cases where a highly optimizing compiler may recognize      
  321.  *  unnecessary statements and may not generate code for them.               
  322.  *                                                                           
  323.  *  There has been no explicit effort to account for the effects of a        
  324.  *  cache, or to balance the use of long or short displacements for code or  
  325.  *  data.                                                                    
  326.  *                                                                           
  327.  ****************************************************************************
  328.  *)
  329.  
  330. program Dhrystone (input, output);
  331. (***************)
  332.  
  333. const (* for measurement *)
  334.  
  335.   MicrosecondsPerClock  = 1000;
  336.   ClocksPerSecond       = 1000;
  337.         (* In Berkeley UNIX Pascal, the function "clock"        *)
  338.         (* returns milliseconds                                 *)
  339.   TooSmallTime          = 2000;
  340.         (* Measurements should last at least 2 seconds          *)
  341.  
  342. type
  343.  
  344.   (* Global type definitions *)
  345.  
  346.   Enumeration           = (Ident1, Ident2, Ident3, Ident4, Ident5);
  347.  
  348.   OneToThirty           = 1..30;
  349.   OneToFifty            = 1..50;
  350.   CapitalLetter         = 'A'..'Z';
  351.  
  352.   String30              = packed array [OneToThirty] of char;
  353.  
  354.   Array1DimInteger      = array [OneToFifty] of integer;
  355.   Array2DimInteger      = array [OneToFifty, OneToFifty] of integer;
  356.  
  357.   RecordPointer         = ^RecordType;
  358.  
  359.   RecordType            =
  360.       record
  361.         PointerComp:   RecordPointer;
  362.         case Discr:    Enumeration of
  363.           Ident1:         (* only this variant is used,           *)
  364.                           (* but in some cases discriminant       *)
  365.                           (* checks are necessary                 *)
  366.             (EnumComp:      Enumeration;
  367.              IntComp:       OneToFifty;
  368.              StringComp:    String30);
  369.           Ident2:
  370.             (Enum2Comp:    Enumeration;
  371.              String2Comp:  String30);
  372.           Ident3, Ident4, Ident5:
  373.             (Char1Comp,
  374.              Char2Comp:    char);
  375.       end; (* record *)
  376.  
  377. var
  378.  
  379.   (* Ada version: Variables local in Proc_0 *)
  380.  
  381.   Int1Glob,
  382.   Int2Glob,
  383.   Int3Glob:       OneToFifty;
  384.   CharIndex:      char;
  385.   EnumGlob:       Enumeration;
  386.   String1Glob,
  387.   String2Glob:    String30;
  388.  
  389.   (* Ada version: Variables global in Pack_1 *)
  390.  
  391.   PointerGlob,
  392.   NextPointerGlob: RecordPointer;
  393.   IntGlob:         integer;
  394.  
  395.   BoolGlob:        boolean;
  396.   Char1Glob,
  397.   Char2Glob:       char;
  398.   Array1Glob:      Array1DimInteger;
  399.   Array2Glob:      Array2DimInteger;
  400.  
  401.   (* Variables for measurement *)
  402.  
  403.   RunIndex,
  404.   NumberOfRuns,
  405.   BeginClock,
  406.   EndClock,
  407.   SumClocks:            integer;
  408.   Microseconds,         
  409.   DhrystonesPerSecond:  real;
  410.   C:                    char;
  411.   I:                    integer;
  412.  
  413.   (* end of variables for measurement *)
  414.  
  415. procedure Proc1 (    PointerParVal: RecordPointer);     forward;
  416.  
  417. procedure Proc2 (var IntParRef:     OneToFifty);        forward;
  418.  
  419. procedure Proc3 (var PointerParRef: RecordPointer);     forward;
  420.  
  421. procedure Proc4;                                        forward;
  422.   (* without parameters *)
  423.  
  424. procedure Proc5;                                        forward;
  425.   (* without parameters *)
  426.  
  427. procedure Proc6 (    EnumParVal:    Enumeration;
  428.                  var EnumParRef:    Enumeration);       forward;
  429.  
  430. procedure Proc7 (    Int1ParVal,
  431.                      Int2ParVal:    OneToFifty;
  432.                  var IntParRef:     OneToFifty);        forward;
  433.  
  434. procedure Proc8 (var Array1ParRef:  Array1DimInteger;
  435.                  var Array2ParRef:  Array2DimInteger;
  436.                      Int1ParVal,
  437.                      Int2ParVal:    integer);            forward;
  438.  
  439. function Func1  (    Char1ParVal,
  440.                      Char2ParVal:   CapitalLetter): 
  441.                                             Enumeration; forward;
  442.  
  443. function Func2  (var String1ParRef,
  444.                      String2ParRef: String30): 
  445.                                             boolean;      forward;
  446.  
  447. function Func3  (    EnumParVal:    Enumeration): 
  448.                                             boolean;      forward;
  449.  
  450.  
  451. procedure Proc1; (* (PointerParVal: RecordPointer) *)
  452.     (* executed once *)
  453. begin
  454.   with PointerParVal^.PointerComp^ (* = PointerGlobNext *) do
  455.   begin
  456.     PointerParVal^.PointerComp^ := PointerGlob^;
  457.     PointerParVal^.IntComp := 5;
  458.     IntComp := PointerParVal^.IntComp;
  459.     PointerComp := PointerParVal^.PointerComp;
  460.     Proc3 (PointerComp);
  461.       (* PointerParVal^.PointerComp^.PointerComp = PointerGlob^.PointerComp *)
  462.     if Discr = Ident1
  463.     then (* executed *)
  464.     begin
  465.       IntComp := 6;
  466.       Proc6 (PointerParVal^.EnumComp, EnumComp);
  467.       PointerComp := PointerGlob^.PointerComp;
  468.       Proc7 (IntComp, 10, IntComp);
  469.     end (* then *)
  470.     else (* not executed *)
  471.       PointerParVal^ := PointerParVal^.PointerComp^;
  472.   end; (* with *)
  473. end; (* Proc1 *)
  474.  
  475.  
  476. procedure Proc2; (* (var IntParRef: OneToFifty) *)
  477.     (* executed once *)
  478.     (* InParRef = 3, becomes 7 *)
  479. var
  480.   IntLoc:  OneToFifty;
  481.   EnumLoc: Enumeration;
  482. begin
  483.   IntLoc := IntParRef + 10;
  484.   repeat (* executed once *)
  485.     if Char1Glob = 'A'
  486.     then (* executed *)
  487.     begin
  488.       IntLoc := IntLoc - 1;
  489.       IntParRef := IntLoc - IntGlob;
  490.       EnumLoc := Ident1;
  491.     end (* if *)
  492.   until EnumLoc = Ident1; (* true *)
  493. end; (* Proc2 *)
  494.  
  495.  
  496. procedure Proc3; (* (var PointerParRef: RecordPointer) *)
  497.     (* executed once *)
  498.     (* PointerParRef becomes PointerGlob *)
  499. begin
  500.   if PointerGlob <> nil
  501.   then (* executed *)
  502.     PointerParRef := PointerGlob^.PointerComp
  503.   else (* not executed *)
  504.     IntGlob := 100;
  505.   Proc7 (10, IntGlob, PointerGlob^.IntComp);
  506. end; (* Proc3 *)
  507.  
  508.  
  509. procedure Proc4; (* without parameters *)
  510.     (* executed once *)
  511. var
  512.   BoolLoc: boolean;
  513. begin
  514.   BoolLoc := Char1Glob = 'A';
  515.   BoolGlob := BoolLoc or BoolGlob;
  516.   Char2Glob := 'B';
  517. end; (* Proc4 *)
  518.  
  519.  
  520. procedure Proc5; (* without parameters *)
  521.     (* executed once *)
  522. begin
  523.   Char1Glob := 'A';
  524.   BoolGlob := false;
  525. end; (* Proc5 *)
  526.  
  527.  
  528. procedure Proc6; (* (    EnumParVal:     Enumeration;
  529.                      var EnumParRef:     Enumeration) *)
  530.     (* executed once *)
  531.     (* EnumParVal = Ident3, EnumParRef becomes Ident2 *)
  532. begin
  533.   EnumParRef := EnumParVal;
  534.   if not Func3 (EnumParVal)
  535.   then (* not executed *)
  536.     EnumParRef := Ident4;
  537.   case EnumParVal of
  538.     Ident1: EnumParRef := Ident1;
  539.     Ident2: if IntGlob > 100
  540.               then EnumParRef := Ident1
  541.               else EnumParRef := Ident4;
  542.     Ident3: EnumParRef := Ident2;    (* executed *)
  543.     Ident4: ;
  544.     Ident5: EnumParRef := Ident3;
  545.   end; (* case *)
  546. end; (* Proc6 *)
  547.  
  548.  
  549. procedure Proc7; (* (    Int1ParVal,
  550.                          Int2ParVal:    OneToFifty;
  551.                      var IntParRef:     OneToFifty) *)
  552.     (* executed three times                               *)
  553.     (* first call:      Int1ParVal = 2, Int2ParVal = 3,   *)
  554.     (*                  IntParRef becomes 7               *)
  555.     (* second call:     Int1ParVal = 10, Int2ParVal = 5,  *)
  556.     (*                  IntParRef becomes 17              *)
  557.     (* third call:      Int1ParVal = 6, Int2ParVal = 10,  *)
  558.     (*                  IntParRef becomes 18              *)
  559. var
  560.   IntLoc: OneToFifty;
  561. begin
  562.   IntLoc := Int1ParVal + 2;
  563.   IntParRef := Int2ParVal + IntLoc;
  564. end; (* Proc7 *)
  565.  
  566.  
  567. procedure Proc8; (* (var Array1ParRef: Array1DimInteger;
  568.                      var Array2ParRef: Array2DimInteger;
  569.                          Int1ParVal,
  570.                          Int2ParVal:    integer)          *)
  571.     (* executed once  *)
  572.     (* Int1ParVal = 3 *)
  573.     (* Int2ParVal = 7 *)
  574. var
  575.   IntIndex,
  576.   IntLoc:   OneToFifty;
  577. begin
  578.   IntLoc := Int1ParVal + 5;
  579.   Array1ParRef [IntLoc] := Int2ParVal;
  580.   Array1ParRef [IntLoc+1] := Array1ParRef [IntLoc];
  581.   Array1ParRef [IntLoc+30] := IntLoc;
  582.   for IntIndex := IntLoc to IntLoc+1 do
  583.     Array2ParRef [IntLoc, IntIndex] := IntLoc;
  584.   Array2ParRef [IntLoc, IntLoc-1] := Array2ParRef [IntLoc, IntLoc-1] + 1;
  585.   Array2ParRef [IntLoc+20, IntLoc] := Array1ParRef [IntLoc];
  586.   IntGlob := 5;
  587. end; (* Proc8 *)
  588.  
  589.  
  590. function Func1; (* (Char1ParVal,
  591.                     Char2ParVal: CapitalLetter): Enumeration *)
  592.     (* executed three times, returns always Ident1              *)
  593.     (* first call:      Char1ParVal = 'H', Char2ParVal = 'R'    *)
  594.     (* second call:     Char1ParVal = 'A', Char2ParVal = 'C'    *)
  595.     (* third call:      Char1ParVal = 'B', Char2ParVal = 'C'    *)
  596. var
  597.   Char1Loc, Char2Loc: CapitalLetter;
  598. begin
  599.   Char1Loc := Char1ParVal;
  600.   Char2Loc := Char1Loc;
  601.   if Char2Loc <> Char2ParVal
  602.   then  (* executed *)
  603.     Func1 := Ident1
  604.   else  (* not executed *)
  605.   begin
  606.     Char1Glob := Char1Loc;
  607.     Func1 := Ident2;
  608.   end;
  609. end; (* Func1 *)
  610.  
  611.  
  612. function Func2; (* (var String1ParRef,
  613.                         String2ParRef: String30): boolean *)
  614.     (* executed once, returns false              *)
  615.     (* String1ParRef = 'DHRYSTONE PROGRAM, 1''ST STRING' *)
  616.     (* String2ParRef = 'DHRYSTONE PROGRAM, 2''ND STRING' *)
  617. var
  618.   IntLoc:  OneToThirty;
  619.   CharLoc: CapitalLetter;
  620. begin
  621.   IntLoc := 2;
  622.   while IntLoc <= 2 do (* loop body executed once *)
  623.     if Func1 (String1ParRef[IntLoc],
  624.               String2ParRef[IntLoc+1]) = Ident1
  625.     then (* executed *)
  626.     begin
  627.       CharLoc := 'A';
  628.       IntLoc := IntLoc + 1;
  629.     end; (* if, while *)
  630.   if (CharLoc >= 'W') and (CharLoc < 'Z')
  631.   then (* not executed *)
  632.     IntLoc := 7;
  633.   if CharLoc = 'R'
  634.   then (* not executed *)
  635.     Func2 := true
  636.   else (* executed *)
  637.   begin
  638.     if String1ParRef > String2ParRef
  639.     then (* not executed *)
  640.     begin
  641.       IntLoc := IntLoc + 7;
  642.       IntGlob := IntLoc;
  643.       Func2 := true
  644.     end
  645.     else (* executed *)
  646.       Func2 := false;
  647.   end; (* if CharLoc *)
  648. end; (* Func2 *)
  649.  
  650.  
  651. function Func3; (* (EnumParVal: Enumeration): boolean *)
  652.     (* executed once, returns true      *)
  653.     (* EnumParVal = Ident3              *)
  654. var
  655.   EnumLoc:  Enumeration;
  656. begin
  657.   EnumLoc := EnumParVal;
  658.   if EnumLoc = Ident3
  659.   then (* executed *)
  660.     Func3 := true;
  661. end; (* Func3 *)
  662.  
  663.  
  664. begin (* main program, corresponds to procedures        *)
  665.       (* Main and Proc_0 in the Ada version             *)
  666.  
  667.   (* Initializations *)
  668.  
  669.   new (NextPointerGlob);
  670.  
  671.   new (PointerGlob);
  672.  
  673.   PointerGlob^.PointerComp := NextPointerGlob;
  674.   PointerGlob^.Discr       := Ident1;
  675.   PointerGlob^.EnumComp    := Ident3;
  676.   PointerGlob^.IntComp     := 40;
  677.   PointerGlob^.StringComp  := 'DHRYSTONE PROGRAM, SOME STRING';
  678.  
  679.   String1Glob := 'DHRYSTONE PROGRAM, 1''ST STRING';
  680.  
  681.   Array2Glob [8,7] := 10;
  682.  
  683.   writeln;
  684.   writeln ('Dhrystone Benchmark, Version Pascal / 2.0');
  685.   writeln;
  686.   writeln ('Please give the number of runs through the benchmark: ');
  687.   readln (NumberOfRuns);
  688.   writeln;
  689.   writeln ('Execution starts, ', NumberOfRuns : 7, ' runs through Dhrystone');
  690.  
  691.   BeginClock := clock;
  692.  
  693.   (***************)
  694.   (* Start timer *)
  695.   (***************)
  696.   
  697.   for RunIndex := 1 to NumberOfRuns do
  698.   begin
  699.  
  700.     Proc5;
  701.     Proc4;
  702.       (* Char1Glob = 'A', Char2Glob = 'B', BoolGlob = false *)
  703.     Int1Glob := 2;
  704.     Int2Glob := 3;
  705.     String2Glob := 'DHRYSTONE PROGRAM, 2''ND STRING';
  706.     EnumGlob := Ident2;
  707.     BoolGlob := not Func2 (String1Glob, String2Glob);
  708.       (* BoolGlob = true *)
  709.     while Int1Glob < Int2Glob do  (* loop body executed once *)
  710.     begin
  711.       Int3Glob := 5 * Int1Glob - Int2Glob;
  712.         (* Int3Glob = 7 *)
  713.       Proc7 (Int1Glob, Int2Glob, Int3Glob);
  714.         (* Int3Glob = 7 *)
  715.       Int1Glob := Int1Glob + 1;
  716.     end; (* while *)
  717.       (* Int1Glob = 3 *)
  718.     Proc8 (Array1Glob, Array2Glob, Int1Glob, Int3Glob);
  719.       (* IntGlob = 5 *)
  720.     Proc1 (PointerGlob);
  721.     for CharIndex := 'A' to Char2Glob do   (* loop body executed twice *)
  722.       if EnumGlob = Func1 (CharIndex, 'C')
  723.         then (* not executed *)
  724.         begin
  725.           Proc6 (Ident1, EnumGlob);
  726.           String2Glob := 'DHRYSTONE PROGRAM, 3''RD STRING';
  727.           Int2Glob := RunIndex;
  728.           IntGlob := RunIndex;
  729.         end;
  730.     (* Int1Glob = 3, Int2Glob = 3, Int3Glob = 7 *)
  731.     Int2Glob := Int2Glob * Int1Glob;
  732.     Int1Glob := Int2Glob div Int3Glob;
  733.     Int2Glob := 7 * (Int2Glob - Int3Glob) - Int1Glob;
  734.       (* Int1Glob = 1, Int2Glob = 13, Int3Glob = 7 *)
  735.     Proc2 (Int1Glob);
  736.       (* Int1Glob = 5 *)
  737.  
  738.   end; (* for RunIndex *)
  739.  
  740.   EndClock := clock;
  741.  
  742.   (**************)
  743.   (* Stop timer *)
  744.   (**************)
  745.  
  746.   writeln ('Execution ends');
  747.   writeln;
  748.   writeln ('Final values of the variables used in the benchmark:');
  749.   writeln;
  750.  
  751.   writeln ('IntGlob:                      ', IntGlob : 5);
  752.   writeln ('        should be:                5');
  753.   write ('BoolGlob:                      ');
  754.   if BoolGlob = true
  755.   then
  756.     writeln ('TRUE')
  757.   else
  758.     writeln ('FALSE');
  759.   writeln ('        should be:             TRUE');
  760.   writeln ('Char1Glob:                        ', Char1Glob);
  761.   writeln ('        should be:                A');
  762.   writeln ('Char2Glob:                        ', Char2Glob);
  763.   writeln ('        should be:                B');
  764.   writeln ('Array1Glob [8]:               ', Array1Glob [8] : 5);
  765.   writeln ('        should be:                7');
  766.   writeln ('Array2Glob [8,7]:             ', Array2Glob [8,7] : 5);
  767.   writeln ('        should be:                NumberOfRuns + 10');
  768.   writeln ('PointerGlob^.Discr:           ', ord (PointerGlob^.Discr) : 5);
  769.   writeln ('        should be:                0');
  770.   writeln ('PointerGlob^.EnumComp:        ', ord (PointerGlob^.EnumComp) : 5);
  771.   writeln ('        should be:                1');
  772.   writeln ('PointerGlob^.IntComp  :       ', PointerGlob^.IntComp : 5);
  773.   writeln ('        should be:               17');
  774.   write   ('PointerGlob^.StringComp:     ');
  775.   for I := 1 to 30 do
  776.     write (PointerGlob^.StringComp [I]);
  777.   writeln;
  778.   writeln ('        should be:           DHRYSTONE PROGRAM, SOME STRING');
  779.   writeln ('NextPointerGlob^.Discr:       ', ord (NextPointerGlob^.Discr) : 5);
  780.   writeln ('        should be:                0');
  781.   writeln ('NextPointerGlob^.EnumComp:    ',
  782.                     ord (NextPointerGlob^.EnumComp) : 5);
  783.   writeln ('        should be:                1');
  784.   writeln ('NextPointerGlob^.IntComp:     ', NextPointerGlob^.IntComp : 5);
  785.   writeln ('        should be:               18');
  786.   write   ('NextPointerGlob^.StringComp: ');
  787.   for I := 1 to 30 do
  788.     write (NextPointerGlob^.StringComp [I]);
  789.   writeln;
  790.   writeln ('        should be:           DHRYSTONE PROGRAM, SOME STRING');
  791.   writeln ('Int1Glob:                     ', Int1Glob : 5);
  792.   writeln ('        should be:                5');
  793.   writeln ('Int2Glob:                     ', Int2Glob : 5);
  794.   writeln ('        should be:               13');
  795.   writeln ('Int3Glob:                     ', Int3Glob : 5);
  796.   writeln ('        should be:                7');
  797.   writeln ('EnumGlob:                     ', ord (EnumGlob) : 5);
  798.   writeln ('        should be:                1');
  799.   write   ('String1Glob:                 ');
  800.   for I := 1 to 30 do
  801.     write (String1Glob [I]);
  802.   writeln;
  803.   writeln ('        should be:           DHRYSTONE PROGRAM, 1''ST STRING');
  804.   write   ('String2Glob:                 ');
  805.   for I := 1 to 30 do
  806.     write (String2Glob [I]);
  807.   writeln;
  808.   writeln ('        should be:           DHRYSTONE PROGRAM, 2''ND STRING');
  809.   writeln;
  810.   writeln;
  811.  
  812.   SumClocks := EndClock - BeginClock;
  813.  
  814.   if SumClocks < TooSmallTime
  815.     then
  816.     begin
  817.       writeln ('Measured time too small to obtain meaningful results');
  818.       writeln ('Please increase number of runs');
  819.       writeln;
  820.     end
  821.     else
  822.     begin
  823.       Microseconds := SumClocks * MicrosecondsPerClock / NumberOfRuns;
  824.       DhrystonesPerSecond := NumberOfRuns * ClocksPerSecond / SumClocks;
  825.       write ('Microseconds for one run through Dhrystone: ');
  826.       writeln (Microseconds : 8 : 1);
  827.       write ('Dhrystones per Second:                      ');
  828.       writeln (DhrystonesPerSecond : 8 : 1);
  829.       writeln;
  830.     end;
  831.   
  832. end.
  833.